/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "构建场景节点.h"


#include "A_引擎/引擎.h"
#include <节点/物体/拾取.h>
#include <节点/空间/场景信息.h>
#include <节点/空间/OpenVDB.h>
#include <节点/插座/list/list物体插座.h>



void on_PropUpdate_节点开启视口射线拾取(S_Props& prop) {
	//C_节点面板* 节点 = ((C_节点面板*)prop.m_部件);
	//C_射线拾取节点* 节点 = dynamic_cast<C_射线拾取节点*>(((C_节点面板*)prop.m_部件)->m_NodeData);
	auto nodes = f_global_get激活节点();
	for (auto 节点 : nodes) {
		节点->f_set是否要更新(true);

		if (节点) {
			if (*((bool*)prop.m_Value)) {
				节点->f_set节点更新方式(E_节点更新方式::e_节点更新_实时);
			}
			else {
				节点->f_set节点更新方式(E_节点更新方式::e_节点更新_被动);
			}
		}
	}

	//auto* 节点 = dynamic_cast<C_射线拾取节点*>((dynamic_cast<C_节点面板*>(f_global_get激活节点())->m_NodeData));

}

static void f_射线物体拾取节点_3D视口更新(C_节点面板* node, S_Scene* scene) {
	C_射线拾取节点* 节点 = dynamic_cast<C_射线拾取节点*>(node->m_NodeData);

	f_surface_关联实例((S_Mesh*)S_框架::g_当前独立显示物体->m_Data[0], 节点->m_GPU射线可视网格);
	f_surface_关联实例((S_Mesh*)S_框架::g_当前独立显示物体->m_Data[1], 节点->m_GPU可视网格);
	
	

	switch (节点->m_输入的数据类型) {
	case E_值类型::e_插座Type_八叉树: {
		S_框架::g_当前独显物体类型 = E_物体数据类型::e_射线拾取八叉树;
		break;
	}
	case E_值类型::e_Type_Vec3: 
	case E_值类型::e_Type_Vec3_Array1D: {
		S_框架::g_当前独显物体类型 = E_物体数据类型::e_射线拾取点;
		break;
	}
	}

	f_global_所在独显模型材质();

}

static void f_射线物体拾取节点_部件构建属性(C_属性栏* plane, S_结构对象指针 obj) {
	C_射线拾取节点* node = dynamic_cast<C_射线拾取节点*>(((C_节点面板*)obj)->m_NodeData);

	std::vector<S_Props> props;

	auto prop = f_alloc_BoolProp(&(node->m_是否以视口射线拾取), L"视口射线拾取");
	prop.m_UI->m_部件 = ((C_节点面板*)obj);
	prop.m_UI->m_Update = on_PropUpdate_节点开启视口射线拾取;
	prop.m_私有 = true;
	props.push_back(prop);

	plane->f_构建属性部件(props);

	f_射线物体拾取节点_3D视口更新(((C_节点面板*)obj), nullptr);
	
}


C_节点面板* f_节点构建_射线物体拾取(S_UI创建环境& ctx, S_设备环境& dev_ctx, C_节点基类* node, C_节点树* tree) {
	if (!node) node = new C_射线拾取节点(dev_ctx);

	C_节点面板* plane = new C_节点面板(node, ctx, E_节点区类型::e_节点区_物体);
	//if (plane == nullptr) {
	//	plane = f_节点创建_UI面板构建(ctx, node, E_节点区类型::e_节点区_物体);
	//}
	f_节点重置_射线物体拾取(plane, node);

	return plane;
}

void f_节点重置_射线物体拾取(C_节点面板* plane, C_节点基类* node) {
	f_节点重构_面板重构(plane, node, E_节点区类型::e_节点区_物体);
	f_节点重构_插座重构(plane, node, E_节点区类型::e_节点区_物体);

	plane->m_属性面板参数构建 = f_射线物体拾取节点_部件构建属性;
	plane->m_ICO = "雷达";
}









static void f_范围拾取节点_3D视口更新(C_节点面板* node, S_Scene* scene) {
	C_范围拾取节点* 节点 = dynamic_cast<C_范围拾取节点*>(node->m_NodeData);

	
	f_surface_关联实例((S_Mesh*)S_框架::g_当前独立显示物体->m_Data[0], 节点->m_GPU可视网格);
	//f_surface_创建实例((S_Mesh*)S_Core::g_当前独立显示物体->m_Data[1], 节点->m_GPU射线可视网格);


	switch (节点->m_输入的数据类型) {
	case E_值类型::e_插座Type_八叉树: {
		S_框架::g_当前独显物体类型 = E_物体数据类型::e_范围拾取八叉树;
		break;
	}
	case E_值类型::e_Type_Vec3:
	case E_值类型::e_Type_Vec3_Array1D: {
		S_框架::g_当前独显物体类型 = E_物体数据类型::e_范围拾取点;
		break;
	}
	}

	f_global_所在独显模型材质();

}

static void f_范围拾取节点_部件构建属性(C_属性栏* plane, S_结构对象指针 obj) {
	C_范围拾取节点* node = dynamic_cast<C_范围拾取节点*>(((C_节点面板*)obj)->m_NodeData);

	std::vector<S_Props> props;

	/*auto prop = f_alloc_BoolProp(&(node->m_是否以视口射线拾取), L"视口射线拾取");
	prop.m_部件 = ((C_节点面板*)obj);
	prop.m_Update = on_PropUpdate_节点开启视口射线拾取;
	props.push_back(prop);*/

	plane->f_构建属性部件(props);

	f_范围拾取节点_3D视口更新(((C_节点面板*)obj), nullptr);

}

C_节点面板* f_节点构建_范围拾取(S_UI创建环境& ctx, S_设备环境& dev_ctx, C_节点基类* node, C_节点树* tree) {
	if (!node) node = new C_范围拾取节点(dev_ctx);
	//if (plane == nullptr) {
	//	plane = f_节点创建_UI面板构建(ctx, node, E_节点区类型::e_节点区_物体);
	//}
	C_节点面板* plane = new C_节点面板(node, ctx, E_节点区类型::e_节点区_物体);
	f_节点重置_范围拾取(plane, node);

	return plane;
}

void		f_节点重置_范围拾取(C_节点面板* plane, C_节点基类* node) {
	f_节点重构_面板重构(plane, node, E_节点区类型::e_节点区_物体);
	f_节点重构_插座重构(plane, node, E_节点区类型::e_节点区_物体);

	plane->m_属性面板参数构建 = f_范围拾取节点_部件构建属性;
	plane->m_ICO = "ico范围拾取0010";
}









static void f_视口手柄节点_部件构建属性(C_属性栏* plane, S_结构对象指针 obj) {
	C_视口物体操作手柄节点* node = dynamic_cast<C_视口物体操作手柄节点*>(((C_节点面板*)obj)->m_NodeData);

	std::vector<S_Props> props;
	f_节点重构_重构属性面板数据((C_节点面板*)obj, props);
	/*auto prop = f_alloc_BoolProp(&(node->m_是否以视口射线拾取), L"视口射线拾取");
	prop.m_部件 = ((C_节点面板*)obj);
	prop.m_Update = on_PropUpdate_节点开启视口射线拾取;
	props.push_back(prop);*/
	plane->f_构建属性部件(props);
}

C_节点面板* f_节点构建_视口手柄(S_UI创建环境& ctx, S_设备环境& dev_ctx, C_节点基类* node, C_节点树* tree) {
	//if (!node) node = new C_视口物体操作手柄节点(dev_ctx);
	//if (plane == nullptr) {
	//	plane = f_节点创建_UI面板构建(ctx, node, E_节点区类型::e_节点区_物体);
	//}
	C_节点面板* plane = new C_节点面板(node, ctx, E_节点区类型::e_节点区_物体);
	f_节点重置_视口手柄(plane, node);
	return plane;
}

void f_节点重置_视口手柄(C_节点面板* plane, C_节点基类* node) {
	f_节点重构_面板重构(plane, node, E_节点区类型::e_节点区_物体);
	f_节点重构_插座重构(plane, node, E_节点区类型::e_节点区_物体);

	plane->m_属性面板参数构建 = f_视口手柄节点_部件构建属性;
	plane->m_ICO = "ico范围拾取0010";
}






static void f_帧时间节点_部件构建属性(C_属性栏* plane, S_结构对象指针 obj) {
	C_帧时间节点* node = dynamic_cast<C_帧时间节点*>(((C_节点面板*)obj)->m_NodeData);

	std::vector<S_Props> props;
	f_节点重构_重构属性面板数据((C_节点面板*)obj, props);
	plane->f_构建属性部件(props);
}

C_节点面板* f_节点构建_帧时间(S_UI创建环境& ctx, S_设备环境& dev_ctx, C_节点基类* node, C_节点树* tree) {
	if (!node) {
		node = new C_帧时间节点(dev_ctx);
		node->m_ICO = "ico_时间0001";
	}
	C_节点面板* plane = new C_节点面板(node, ctx, E_节点区类型::e_节点区_物体);
	f_节点重置_帧时间(plane, node);
	return plane;
}

void f_节点重置_帧时间(C_节点面板* plane, C_节点基类* node) {
	f_节点重构_面板插座重构(plane, node, E_节点区类型::e_节点区_物体);
	plane->m_属性面板参数构建 = f_帧时间节点_部件构建属性;
	plane->m_ICO = node->m_ICO;
}






static void f_OpenVDB网格节点_部件构建属性(C_属性栏* plane, S_结构对象指针 obj) {
	C_OpenVDB网格节点* node = dynamic_cast<C_OpenVDB网格节点*>(((C_节点面板*)obj)->m_NodeData);

	std::vector<S_Props> props;
	f_节点重构_重构属性面板数据((C_节点面板*)obj, props);
	/*auto prop = f_alloc_BoolProp(&(node->m_是否以视口射线拾取), L"视口射线拾取");
	prop.m_部件 = ((C_节点面板*)obj);
	prop.m_Update = on_PropUpdate_节点开启视口射线拾取;
	props.push_back(prop);*/
	plane->f_构建属性部件(props);
}

C_节点面板* f_节点构建_OpenVDB网格(S_UI创建环境& ctx, S_设备环境& dev_ctx, C_节点基类* node, C_节点树* tree) {
	if (!node) {
		node = new C_OpenVDB网格节点(dev_ctx);
		node->m_ICO = "ico范围拾取0010";
	}
	C_节点面板* plane = new C_节点面板(node, ctx, E_节点区类型::e_节点区_物体);
	f_节点重置_OpenVDB网格(plane, node);
	return plane;
}

void f_节点重置_OpenVDB网格(C_节点面板* plane, C_节点基类* node) {
	f_节点重构_面板插座重构(plane, node, E_节点区类型::e_节点区_物体);
	plane->m_属性面板参数构建 = f_OpenVDB网格节点_部件构建属性;
	plane->m_ICO = node->m_ICO;
}
















bool f_场景节点重构(C_节点面板** plane, C_节点基类* node, S_UI创建环境* ctx) {
	if (node->m_TypeName == "场景节点") {
		return false;
	}
	else if (node->m_TypeName == "射线拾取节点") {
		if (!plane[0]) plane[0] = f_节点构建_射线物体拾取(*ctx, *S_框架::g_3D视口环境, node);
		f_节点重置_射线物体拾取(plane[0], node);
	}
	else if (node->m_TypeName == "范围拾取节点") {
		if (!plane[0]) plane[0] = f_节点构建_范围拾取(*ctx, *S_框架::g_3D视口环境, node);
		f_节点重置_范围拾取(plane[0], node);
	}
	else if (node->m_TypeName == "帧时间节点") {
		if (!plane[0]) plane[0] = f_节点构建_帧时间(*ctx, *S_框架::g_3D视口环境, node);
		f_节点重置_帧时间(plane[0], node);
	}
	else if (node->m_TypeName == "OpenVDB网格节点") {
		if (!plane[0]) plane[0] = f_节点构建_OpenVDB网格(*ctx, *S_框架::g_3D视口环境, node);
		f_节点重置_OpenVDB网格(plane[0], node);
	}
	else if (node->m_TypeName == "视口物体操作手柄节点") {
		if (!plane[0]) plane[0] = f_节点构建_视口手柄(*ctx, *S_框架::g_3D视口环境, node);
		f_节点重置_视口手柄(plane[0], node);
	}
	else {
		return false;
	}

	return true;
}










